<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>本地图床</title>
  <script src="https://cdn.jsdelivr.net/npm/axios@1.4.0/dist/axios.min.js"></script>
  <script src="https://cdn.tailwindcss.com"></script>
  <link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">
  
  <script>
    tailwind.config = {
      theme: {
        extend: {
          colors: {
            primary: '#165DFF',
            secondary: '#0FC6C2',
            success: '#00B42A',
            warning: '#FF7D00',
            danger: '#F53F3F',
            info: '#86909C',
            light: '#F2F3F5',
            dark: '#1D2129',
          },
          fontFamily: {
            inter: ['Inter', 'system-ui', 'sans-serif'],
          },
        },
      }
    }
  </script>
  
  <style type="text/tailwindcss">
    @layer utilities {
      .content-auto {
        content-visibility: auto;
      }
      .card-shadow {
        box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
      }
      .image-grid {
        display: grid;
        grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
        gap: 1.5rem;
      }
      .scale-hover {
        transition: transform 0.3s ease, box-shadow 0.3s ease;
      }
      .scale-hover:hover {
        transform: translateY(-5px);
        box-shadow: 0 10px 25px rgba(22, 93, 255, 0.15);
      }
      .btn-primary {
        @apply bg-primary text-white px-4 py-2 rounded-lg transition-all duration-300 hover:bg-primary/90 focus:ring-2 focus:ring-primary/50 focus:outline-none;
      }
      .btn-secondary {
        @apply bg-white text-primary border border-primary px-4 py-2 rounded-lg transition-all duration-300 hover:bg-primary/5 focus:ring-2 focus:ring-primary/50 focus:outline-none;
      }
      .btn-danger {
        @apply bg-danger text-white px-4 py-2 rounded-lg transition-all duration-300 hover:bg-danger/90 focus:ring-2 focus:ring-danger/50 focus:outline-none;
      }
    }
  </style>
</head>
<body class="font-inter bg-gray-50 text-dark">
  <div id="app" class="min-h-screen flex flex-col">
    <!-- 导航栏 -->
    <nav class="bg-white shadow-md sticky top-0 z-50">
      <div class="container mx-auto px-4 py-3 flex justify-between items-center">
        <div class="flex items-center space-x-2">
          <i class="fa fa-picture-o text-primary text-2xl"></i>
          <h1 class="text-xl font-bold text-primary">本地图床</h1>
        </div>
        
        <div class="flex items-center space-x-4">
          <button id="adminLoginBtn" class="hidden md:flex items-center space-x-1 text-primary hover:text-primary/80 transition-colors">
            <i class="fa fa-user-secret"></i>
            <span>管理员</span>
          </button>
          <button id="adminLoginBtnMobile" class="md:hidden text-primary">
            <i class="fa fa-user-secret text-xl"></i>
          </button>
        </div>
      </div>
    </nav>
    
    <!-- 管理员登录模态框 -->
    <div id="adminLoginModal" class="fixed inset-0 bg-black/50 flex items-center justify-center z-50 hidden">
      <div class="bg-white rounded-xl p-6 w-full max-w-md mx-4 transform transition-all scale-100 opacity-100">
        <div class="flex justify-between items-center mb-4">
          <h3 class="text-lg font-semibold text-dark">管理员登录</h3>
          <button id="closeAdminLogin" class="text-gray-400 hover:text-gray-600">
            <i class="fa fa-times"></i>
          </button>
        </div>
        
        <div class="mb-4">
          <label for="adminPassword" class="block text-sm font-medium text-gray-700 mb-1">密码</label>
          <input 
            type="password" 
            id="adminPassword" 
            class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary/50 focus:border-primary outline-none transition-all"
            placeholder="请输入管理员密码"
          >
        </div>
        
        <div class="flex justify-end">
          <button id="adminLoginSubmit" class="btn-primary">
            登录
          </button>
        </div>
      </div>
    </div>
    
    <!-- 主要内容 -->
    <main class="flex-grow container mx-auto px-4 py-8">
      <!-- 管理面板 (只有管理员登录后可见) -->
      <div id="adminPanel" class="bg-white rounded-xl p-6 mb-8 card-shadow hidden">
        <div class="flex justify-between items-center mb-6">
          <h2 class="text-xl font-bold text-dark">管理面板</h2>
          <button id="logoutBtn" class="text-sm text-danger hover:text-danger/80 transition-colors flex items-center">
            <i class="fa fa-sign-out mr-1"></i> 退出登录
          </button>
        </div>
        
        <!-- 上传区域 -->
        <div id="uploadArea" class="border-2 border-dashed border-gray-300 rounded-lg p-8 text-center hover:border-primary transition-colors cursor-pointer mb-8">
          <input 
            type="file" 
            id="fileInput" 
            accept="image/*" 
            class="hidden"
          >
          
          <i class="fa fa-cloud-upload text-4xl text-gray-400 mb-4"></i>
          <h3 class="text-lg font-medium text-gray-700 mb-2">拖放图片到此处上传</h3>
          <p class="text-sm text-gray-500">或者点击选择图片文件 (支持 JPG, PNG, GIF 等格式)</p>
        </div>
        
        <!-- 上传进度条 -->
        <div id="uploadProgressContainer" class="mb-6 hidden">
          <div class="flex justify-between text-sm mb-1">
            <span>上传中...</span>
            <span id="uploadProgressText">0%</span>
          </div>
          <div class="w-full bg-gray-200 rounded-full h-2.5">
            <div id="uploadProgressBar" class="bg-primary h-2.5 rounded-full" style="width: 0%"></div>
          </div>
        </div>
        
        <!-- 管理工具栏 -->
        <div class="flex flex-col md:flex-row justify-between items-start md:items-center mb-6 gap-4">
          <div class="flex items-center space-x-2">
            <button id="selectAllBtn" class="btn-secondary text-sm">
              全选
            </button>
            <button id="deleteSelectedBtn" class="btn-danger text-sm" disabled>
              删除选中
            </button>
          </div>
          
          <div class="relative w-full md:w-64">
            <input 
              type="text" 
              id="searchQuery" 
              placeholder="搜索图片..." 
              class="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary/50 focus:border-primary outline-none transition-all"
            >
            <i class="fa fa-search absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400"></i>
          </div>
        </div>
        
        <!-- 图片统计 -->
        <div class="grid grid-cols-1 md:grid-cols-3 gap-4 mb-6">
          <div class="bg-blue-50 rounded-lg p-4 flex items-center">
            <div class="bg-blue-100 rounded-full p-3 mr-4">
              <i class="fa fa-image text-primary"></i>
            </div>
            <div>
              <p class="text-sm text-gray-500">总图片数</p>
              <p class="text-2xl font-bold text-dark" id="totalImages">0</p>
            </div>
          </div>
          
          <div class="bg-green-50 rounded-lg p-4 flex items-center">
            <div class="bg-green-100 rounded-full p-3 mr-4">
              <i class="fa fa-eye text-success"></i>
            </div>
            <div>
              <p class="text-sm text-gray-500">公开图片</p>
              <p class="text-2xl font-bold text-dark" id="publicImages">0</p>
            </div>
          </div>
          
          <div class="bg-yellow-50 rounded-lg p-4 flex items-center">
            <div class="bg-yellow-100 rounded-full p-3 mr-4">
              <i class="fa fa-calendar text-warning"></i>
            </div>
            <div>
              <p class="text-sm text-gray-500">本周上传</p>
              <p class="text-2xl font-bold text-dark" id="thisWeekImages">0</p>
            </div>
          </div>
        </div>
      </div>
      
      <!-- 图片网格 -->
      <div id="imageGrid" class="image-grid">
        <!-- 加载中 -->
        <div id="loadingIndicator" class="col-span-full flex justify-center items-center py-12">
          <div class="animate-spin rounded-full h-12 w-12 border-t-2 border-b-2 border-primary"></div>
        </div>
        
        <!-- 没有图片 -->
        <div id="noImagesMessage" class="col-span-full flex flex-col items-center justify-center py-12 text-center hidden">
          <i class="fa fa-folder-open-o text-5xl text-gray-300 mb-4"></i>
          <p class="text-gray-500">暂无图片</p>
          <p id="noImagesAdminMessage" class="text-sm text-gray-400 mt-2 hidden">请上传图片到图床</p>
        </div>
        
        <!-- 图片将通过JavaScript动态添加 -->
      </div>
      
      <!-- 分页控件 -->
      <div id="paginationControls" class="mt-8 flex justify-center hidden">
        <nav class="flex items-center space-x-1">
          <button id="prevPageBtn" class="px-3 py-2 rounded-lg border border-gray-300 text-gray-500 hover:bg-gray-50 disabled:opacity-50 disabled:hover:bg-transparent transition-colors" disabled>
            <i class="fa fa-chevron-left"></i>
          </button>
          
          <!-- 页码将通过JavaScript动态添加 -->
          
          <button id="nextPageBtn" class="px-3 py-2 rounded-lg border border-gray-300 text-gray-500 hover:bg-gray-50 disabled:opacity-50 disabled:hover:bg-transparent transition-colors" disabled>
            <i class="fa fa-chevron-right"></i>
          </button>
        </nav>
      </div>
    </main>
    
    <!-- 页脚 -->
    <footer class="bg-white border-t border-gray-200 py-6">
      <div class="container mx-auto px-4 text-center text-gray-500 text-sm">
        <p>© 2025 本地图床 | 一个简单的图片管理系统</p>
      </div>
    </footer>
    
    <!-- 图片查看模态框 -->
    <div id="imageModal" class="fixed inset-0 bg-black/80 flex items-center justify-center z-50 hidden">
      <div class="bg-white rounded-xl max-w-4xl w-full max-h-[90vh] overflow-hidden">
        <div class="p-4 flex justify-between items-center border-b border-gray-200">
          <h3 id="modalImageTitle" class="font-semibold text-dark">图片详情</h3>
          <button id="closeImageModal" class="text-gray-400 hover:text-gray-600">
            <i class="fa fa-times"></i>
          </button>
        </div>
        
        <div class="p-4 flex flex-col md:flex-row gap-4">
          <div class="w-full md:w-2/3 flex justify-center">
            <img 
              id="modalImage" 
              src="" 
              alt="" 
              class="max-w-full max-h-[60vh] object-contain"
            >
          </div>
          
          <div class="w-full md:w-1/3 bg-gray-50 rounded-lg p-4">
            <h4 class="font-medium text-dark mb-3">图片信息</h4>
            
            <div class="space-y-3">
              <div>
                <p class="text-sm text-gray-500">原始文件名</p>
                <p id="modalOriginalName"></p>
              </div>
              
              <div>
                <p class="text-sm text-gray-500">上传日期</p>
                <p id="modalUploadDate"></p>
              </div>
              
              <div>
                <p class="text-sm text-gray-500">URL</p>
                <div class="relative mt-1">
                  <input 
                    type="text" 
                    id="modalImageUrl" 
                    readonly 
                    class="w-full bg-white text-sm px-3 py-2 rounded border border-gray-200 pr-10"
                  >
                  <button id="copyModalUrlBtn" class="absolute right-2 top-1/2 transform -translate-y-1/2 text-gray-400 hover:text-primary">
                    <i class="fa fa-clipboard"></i>
                  </button>
                </div>
              </div>
              
              <div id="modalStatusContainer" class="hidden">
                <p class="text-sm text-gray-500">状态</p>
                <label class="relative inline-flex items-center cursor-pointer">
                  <input type="checkbox" id="modalImageStatus" class="sr-only peer">
                  <div class="w-11 h-6 bg-gray-200 peer-focus:outline-none rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-primary"></div>
                  <span id="modalStatusText" class="ml-3 text-sm font-medium text-gray-700">公开</span>
                </label>
              </div>
              
              <div id="modalDeleteBtnContainer" class="mt-4 hidden">
                <button id="modalDeleteBtn" class="btn-danger w-full">
                  <i class="fa fa-trash mr-1"></i> 删除图片
                </button>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
    
    <!-- 通知提示 -->
    <div id="notification" class="fixed bottom-4 right-4 bg-white rounded-lg shadow-lg p-4 transform transition-all duration-300 translate-y-20 opacity-0 z-50 flex items-center max-w-sm">
      <div id="notification-icon" class="mr-3 text-lg">
        <i class="fa fa-check-circle text-success"></i>
      </div>
      <div>
        <h4 id="notification-title" class="font-medium text-dark">操作成功</h4>
        <p id="notification-message" class="text-sm text-gray-500">图片已成功上传</p>
      </div>
      <button id="close-notification" class="ml-4 text-gray-400 hover:text-gray-600">
        <i class="fa fa-times"></i>
      </button>
    </div>
  </div>

  <script>
    // 应用状态
    const state = {
      images: [],
      currentPage: 1,
      totalPages: 1,
      totalImages: 0,
      publicImages: 0,
      thisWeekImages: 0,
      isAdmin: false,
      selectedImages: [],
      currentImageId: null,
      searchQuery: '',
      debounceTimer: null
    };

    // DOM 元素
    const elements = {
      adminPanel: document.getElementById('adminPanel'),
      adminLoginModal: document.getElementById('adminLoginModal'),
      fileInput: document.getElementById('fileInput'),
      uploadArea: document.getElementById('uploadArea'),
      uploadProgressContainer: document.getElementById('uploadProgressContainer'),
      uploadProgressBar: document.getElementById('uploadProgressBar'),
      uploadProgressText: document.getElementById('uploadProgressText'),
      selectAllBtn: document.getElementById('selectAllBtn'),
      deleteSelectedBtn: document.getElementById('deleteSelectedBtn'),
      searchQuery: document.getElementById('searchQuery'),
      totalImages: document.getElementById('totalImages'),
      publicImages: document.getElementById('publicImages'),
      thisWeekImages: document.getElementById('thisWeekImages'),
      imageGrid: document.getElementById('imageGrid'),
      loadingIndicator: document.getElementById('loadingIndicator'),
      noImagesMessage: document.getElementById('noImagesMessage'),
      noImagesAdminMessage: document.getElementById('noImagesAdminMessage'),
      paginationControls: document.getElementById('paginationControls'),
      prevPageBtn: document.getElementById('prevPageBtn'),
      nextPageBtn: document.getElementById('nextPageBtn'),
      imageModal: document.getElementById('imageModal'),
      modalImage: document.getElementById('modalImage'),
      modalImageTitle: document.getElementById('modalImageTitle'),
      modalOriginalName: document.getElementById('modalOriginalName'),
      modalUploadDate: document.getElementById('modalUploadDate'),
      modalImageUrl: document.getElementById('modalImageUrl'),
      modalStatusContainer: document.getElementById('modalStatusContainer'),
      modalImageStatus: document.getElementById('modalImageStatus'),
      modalStatusText: document.getElementById('modalStatusText'),
      modalDeleteBtnContainer: document.getElementById('modalDeleteBtnContainer'),
      modalDeleteBtn: document.getElementById('modalDeleteBtn'),
      copyModalUrlBtn: document.getElementById('copyModalUrlBtn'),
      notification: document.getElementById('notification'),
      notificationTitle: document.getElementById('notification-title'),
      notificationMessage: document.getElementById('notification-message'),
      notificationIcon: document.getElementById('notification-icon'),
      logoutBtn: document.getElementById('logoutBtn'),
      adminLoginBtn: document.getElementById('adminLoginBtn'),
      adminLoginBtnMobile: document.getElementById('adminLoginBtnMobile'),
      adminLoginSubmit: document.getElementById('adminLoginSubmit'),
      closeAdminLogin: document.getElementById('closeAdminLogin'),
      closeImageModal: document.getElementById('closeImageModal'),
      closeNotification: document.getElementById('close-notification')
    };

    // 初始化应用
    function initApp() {
      // 检查是否已登录
      state.isAdmin = localStorage.getItem('adminLoggedIn') === 'true';
      updateAdminUI();
      
      // 绑定事件
      bindEvents();
      
      // 获取图片列表
      fetchImages();
    }

    // 绑定事件处理程序
    function bindEvents() {
      // 管理员登录相关
      elements.adminLoginBtn.addEventListener('click', toggleAdminLoginModal);
      elements.adminLoginBtnMobile.addEventListener('click', toggleAdminLoginModal);
      elements.adminLoginSubmit.addEventListener('click', handleAdminLogin);
      elements.closeAdminLogin.addEventListener('click', toggleAdminLoginModal);
      elements.logoutBtn.addEventListener('click', handleLogout);
      
      // 图片上传相关
      elements.uploadArea.addEventListener('click', () => elements.fileInput.click());
      elements.fileInput.addEventListener('change', handleFileUpload);
      
      // 图片管理相关
      elements.selectAllBtn.addEventListener('click', toggleSelectAll);
      elements.deleteSelectedBtn.addEventListener('click', deleteSelectedImages);
      elements.searchQuery.addEventListener('input', debounce(handleSearch, 300));
      
      // 分页相关
      elements.prevPageBtn.addEventListener('click', goToPrevPage);
      elements.nextPageBtn.addEventListener('click', goToNextPage);
      
      // 模态框相关
      elements.closeImageModal.addEventListener('click', closeImageModal);
      elements.modalDeleteBtn.addEventListener('click', deleteCurrentImage);
      elements.modalImageStatus.addEventListener('change', toggleCurrentImageStatus);
      elements.copyModalUrlBtn.addEventListener('click', copyModalUrl);
      
      // 通知相关
      elements.closeNotification.addEventListener('click', hideNotification);
    }

    // 获取图片列表
    function fetchImages() {
      elements.loadingIndicator.classList.remove('hidden');
      elements.imageGrid.innerHTML = '';
      
      axios.get(`/api/images?page=${state.currentPage}`)
        .then(response => {
          state.images = response.data.items;
          state.totalPages = response.data.total_pages;
          state.totalImages = response.data.total_items;
          
          // 更新统计信息
          elements.totalImages.textContent = state.totalImages;
          
          // 计算公开图片数量
          state.publicImages = state.images.filter(img => img.is_public).length;
          elements.publicImages.textContent = state.publicImages;
          
          // 计算本周上传的图片数量
          const oneWeekAgo = new Date();
          oneWeekAgo.setDate(oneWeekAgo.getDate() - 7);
          state.thisWeekImages = state.images.filter(img => {
            const uploadDate = new Date(img.upload_date);
            return uploadDate >= oneWeekAgo;
          }).length;
          elements.thisWeekImages.textContent = state.thisWeekImages;
          
          // 渲染图片
          renderImages();
          
          // 更新分页控件
          updatePagination();
        })
        .catch(error => {
          console.error('获取图片列表失败:', error);
          showNotification('错误', '获取图片列表失败', 'error');
        })
        .finally(() => {
          elements.loadingIndicator.classList.add('hidden');
        });
    }

    // 渲染图片
    function renderImages() {
      if (state.images.length === 0) {
        elements.noImagesMessage.classList.remove('hidden');
        if (state.isAdmin) {
          elements.noImagesAdminMessage.classList.remove('hidden');
        } else {
          elements.noImagesAdminMessage.classList.add('hidden');
        }
        return;
      }
      
      elements.noImagesMessage.classList.add('hidden');
      
      state.images.forEach(image => {
        const card = createImageCard(image);
        elements.imageGrid.appendChild(card);
      });
    }

    // 创建图片卡片
    function createImageCard(image) {
      const card = document.createElement('div');
      card.className = 'bg-white rounded-xl overflow-hidden card-shadow scale-hover';
      card.dataset.id = image.id;
      
      const isSelected = state.selectedImages.includes(image.id);
      
      card.innerHTML = `
        <div class="relative">
          <img 
            src="${image.url}" 
            alt="${image.original_name}" 
            class="w-full h-60 object-cover cursor-pointer"
            data-id="${image.id}"
          >
          
          <!-- 管理控件 (只有管理员登录后可见) -->
          <div class="admin-controls absolute top-2 right-2 flex space-x-1 ${state.isAdmin ? '' : 'hidden'}">
            <label class="relative inline-flex items-center cursor-pointer">
              <input type="checkbox" class="image-select-checkbox sr-only peer" data-id="${image.id}" ${isSelected ? 'checked' : ''}>
              <div class="w-5 h-5 border border-gray-300 rounded peer peer-checked:bg-primary peer-checked:border-primary transition-colors"></div>
            </label>
            
            <button class="toggle-public-btn bg-white/80 hover:bg-white p-1.5 rounded-full transition-colors" data-id="${image.id}">
              <i class="${image.is_public ? 'fa fa-eye text-success' : 'fa fa-eye-slash text-gray-500'}"></i>
            </button>
            
            <button class="delete-btn bg-white/80 hover:bg-white p-1.5 rounded-full transition-colors" data-id="${image.id}">
              <i class="fa fa-trash text-danger"></i>
            </button>
          </div>
          
          <!-- 图片状态标签 -->
          <div class="${!image.is_public ? 'absolute bottom-2 left-2 bg-dark/70 text-white text-xs px-2 py-1 rounded' : 'hidden'}">
            私有
          </div>
        </div>
        
        <div class="p-4">
          <h3 class="font-medium text-dark truncate">${image.original_name}</h3>
          <p class="text-sm text-gray-500 mt-1">
            <i class="fa fa-calendar-o mr-1"></i> 
            ${formatDate(image.upload_date)}
          </p>
          
          <!-- 图片URL (只有管理员登录后可见) -->
          <div class="${state.isAdmin ? '' : 'hidden'} mt-3">
            <div class="relative">
              <input 
                type="text" 
                value="${image.url}" 
                readonly 
                class="w-full bg-gray-50 text-sm px-3 py-2 rounded border border-gray-200 pr-10"
              >
              <button class="copy-url-btn absolute right-2 top-1/2 transform -translate-y-1/2 text-gray-400 hover:text-primary" data-url="${image.url}">
                <i class="fa fa-clipboard"></i>
              </button>
            </div>
          </div>
        </div>
      `;
      
      // 绑定图片点击事件
      const img = card.querySelector('img[data-id]');
      img.addEventListener('click', () => openImageModal(image));
      
      // 绑定管理控件事件
      if (state.isAdmin) {
        const selectCheckbox = card.querySelector('.image-select-checkbox');
        selectCheckbox.addEventListener('change', (e) => handleImageSelect(e, image.id));
        
        const togglePublicBtn = card.querySelector('.toggle-public-btn');
        togglePublicBtn.addEventListener('click', (e) => {
          e.stopPropagation();
          toggleImageStatus(image.id);
        });
        
        const deleteBtn = card.querySelector('.delete-btn');
        deleteBtn.addEventListener('click', (e) => {
          e.stopPropagation();
          deleteImage(image.id);
        });
        
        const copyUrlBtn = card.querySelector('.copy-url-btn');
        copyUrlBtn.addEventListener('click', (e) => {
          e.stopPropagation();
          copyToClipboard(image.url);
        });
      }
      
      return card;
    }

    // 更新分页控件
    function updatePagination() {
      if (state.totalPages <= 1) {
        elements.paginationControls.classList.add('hidden');
        return;
      }
      
      elements.paginationControls.classList.remove('hidden');
      
      // 更新上一页按钮状态
      elements.prevPageBtn.disabled = state.currentPage === 1;
      
      // 更新下一页按钮状态
      elements.nextPageBtn.disabled = state.currentPage === state.totalPages;
      
      // 清空页码
      const paginationNav = elements.paginationControls.querySelector('nav');
      const prevBtn = elements.prevPageBtn;
      const nextBtn = elements.nextPageBtn;
      
      // 移除页码按钮
      while (paginationNav.children.length > 2) {
        paginationNav.removeChild(paginationNav.children[1]);
      }
      
      // 添加页码按钮
      for (let i = 1; i <= state.totalPages; i++) {
        const pageBtn = document.createElement('button');
        pageBtn.className = `px-4 py-2 rounded-lg border border-gray-300 text-gray-700 hover:bg-gray-50 transition-colors ${i === state.currentPage ? 'bg-primary text-white border-primary' : ''}`;
        pageBtn.textContent = i;
        pageBtn.addEventListener('click', () => goToPage(i));
        
        paginationNav.insertBefore(pageBtn, nextBtn);
      }
    }

    // 前往上一页
    function goToPrevPage() {
      if (state.currentPage > 1) {
        state.currentPage--;
        fetchImages();
      }
    }

    // 前往下一页
    function goToNextPage() {
      if (state.currentPage < state.totalPages) {
        state.currentPage++;
        fetchImages();
      }
    }

    // 前往指定页
    function goToPage(page) {
      if (page >= 1 && page <= state.totalPages) {
        state.currentPage = page;
        fetchImages();
      }
    }

    // 打开图片模态框
    function openImageModal(image) {
      state.currentImageId = image.id;
      
      elements.modalImage.src = image.url;
      elements.modalImage.alt = image.original_name;
      elements.modalImageTitle.textContent = image.original_name;
      elements.modalOriginalName.textContent = image.original_name;
      elements.modalUploadDate.textContent = formatDate(image.upload_date);
      elements.modalImageUrl.value = image.url;
      
      if (state.isAdmin) {
        elements.modalStatusContainer.classList.remove('hidden');
        elements.modalDeleteBtnContainer.classList.remove('hidden');
        elements.modalImageStatus.checked = image.is_public;
        elements.modalStatusText.textContent = image.is_public ? '公开' : '私有';
      } else {
        elements.modalStatusContainer.classList.add('hidden');
        elements.modalDeleteBtnContainer.classList.add('hidden');
      }
      
      elements.imageModal.classList.remove('hidden');
    }

    // 关闭图片模态框
    function closeImageModal() {
      elements.imageModal.classList.add('hidden');
      state.currentImageId = null;
    }

    // 删除当前查看的图片
    function deleteCurrentImage() {
      if (state.currentImageId) {
        deleteImage(state.currentImageId);
        closeImageModal();
      }
    }

    // 切换当前图片状态
    function toggleCurrentImageStatus() {
      if (state.currentImageId) {
        const image = state.images.find(img => img.id === state.currentImageId);
        if (image) {
          toggleImageStatus(image.id);
        }
      }
    }

    // 复制模态框中的URL
    function copyModalUrl() {
      copyToClipboard(elements.modalImageUrl.value);
    }

    // 删除图片
    function deleteImage(id) {
      if (confirm('确定要删除这张图片吗？')) {
        axios.delete(`/api/admin/images/${id}`, {
          headers: {
            'Admin-Password': localStorage.getItem('adminPassword')
          }
        })
          .then(() => {
            const index = state.images.findIndex(img => img.id === id);
            if (index !== -1) {
              const deletedImage = state.images[index];
              state.images.splice(index, 1);
              state.totalImages--;
              if (deletedImage.is_public) {
                state.publicImages--;
              }
              elements.totalImages.textContent = state.totalImages;
              elements.publicImages.textContent = state.publicImages;
              
              // 从DOM中移除卡片
              const card = document.querySelector(`.image-grid > div[data-id="${id}"]`);
              if (card) {
                card.remove();
              }
              
              // 更新选中状态
              const selectedIndex = state.selectedImages.indexOf(id);
              if (selectedIndex !== -1) {
                state.selectedImages.splice(selectedIndex, 1);
              }
              
              // 如果没有图片了，显示空状态
              if (state.images.length === 0) {
                renderImages();
              }
              
              showNotification('成功', '图片已删除', 'success');
            }
          })
          .catch(error => {
            console.error('删除图片失败:', error);
            showNotification('错误', '删除图片失败', 'error');
          });
      }
    }

    // 切换图片公开状态
    function toggleImageStatus(id) {
      axios.put(`/api/admin/images/${id}/public`, {}, {
        headers: {
          'Admin-Password': localStorage.getItem('adminPassword')
        }
      })
        .then(response => {
          const image = state.images.find(img => img.id === id);
          if (image) {
            image.is_public = response.data.is_public;
            
            // 更新DOM中的状态图标
            const card = document.querySelector(`.image-grid > div[data-id="${id}"]`);
            if (card) {
              const icon = card.querySelector('.toggle-public-btn i');
              if (icon) {
                icon.className = image.is_public ? 'fa fa-eye text-success' : 'fa fa-eye-slash text-gray-500';
              }
              
              // 更新状态标签
              const statusLabel = card.querySelector('.absolute.bottom-2.left-2');
              if (statusLabel) {
                if (image.is_public) {
                  statusLabel.classList.add('hidden');
                } else {
                  statusLabel.classList.remove('hidden');
                }
              }
            }
            
            // 更新模态框中的状态
            if (state.currentImageId === id) {
              elements.modalImageStatus.checked = image.is_public;
              elements.modalStatusText.textContent = image.is_public ? '公开' : '私有';
            }
            
            // 更新公开图片计数
            state.publicImages = state.images.filter(img => img.is_public).length;
            elements.publicImages.textContent = state.publicImages;
            
            showNotification('成功', `图片已设为${image.is_public ? '公开' : '私有'}`, 'success');
          }
        })
        .catch(error => {
          console.error('切换图片状态失败:', error);
          showNotification('错误', '切换图片状态失败', 'error');
        });
    }

    // 处理图片选择
    function handleImageSelect(event, id) {
      const isChecked = event.target.checked;
      
      if (isChecked) {
        if (!state.selectedImages.includes(id)) {
          state.selectedImages.push(id);
        }
      } else {
        const index = state.selectedImages.indexOf(id);
        if (index !== -1) {
          state.selectedImages.splice(index, 1);
        }
      }
      
      // 更新删除按钮状态
      elements.deleteSelectedBtn.disabled = state.selectedImages.length === 0;
      
      // 更新全选按钮状态
      updateSelectAllButton();
    }

    // 全选/取消全选
    function toggleSelectAll() {
      if (state.selectedImages.length === state.images.length) {
        // 如果已经全选，则取消全选
        state.selectedImages = [];
      } else {
        // 否则全选
        state.selectedImages = state.images.map(img => img.id);
      }
      
      // 更新复选框状态
      document.querySelectorAll('.image-select-checkbox').forEach(checkbox => {
        checkbox.checked = state.selectedImages.includes(parseInt(checkbox.dataset.id));
      });
      
      // 更新删除按钮状态
      elements.deleteSelectedBtn.disabled = state.selectedImages.length === 0;
      
      // 更新全选按钮状态
      updateSelectAllButton();
    }

    // 更新全选按钮状态
    function updateSelectAllButton() {
      elements.selectAllBtn.textContent = state.selectedImages.length === state.images.length ? '取消全选' : '全选';
    }

    // 删除选中的图片
    function deleteSelectedImages() {
      if (state.selectedImages.length === 0) return;
      
      if (confirm(`确定要删除选中的 ${state.selectedImages.length} 张图片吗？`)) {
        const deletePromises = state.selectedImages.map(id => {
          return axios.delete(`/api/admin/images/${id}`, {
            headers: {
              'Admin-Password': localStorage.getItem('adminPassword')
            }
          });
        });
        
        Promise.all(deletePromises)
          .then(() => {
            // 从状态中移除已删除的图片
            state.images = state.images.filter(img => !state.selectedImages.includes(img.id));
            state.totalImages -= state.selectedImages.length;
            state.publicImages = state.images.filter(img => img.is_public).length;
            
            // 更新DOM
            state.selectedImages.forEach(id => {
              const card = document.querySelector(`.image-grid > div[data-id="${id}"]`);
              if (card) {
                card.remove();
              }
            });
            
            // 更新统计信息
            elements.totalImages.textContent = state.totalImages;
            elements.publicImages.textContent = state.publicImages;
            
            // 重置选中状态
            state.selectedImages = [];
            elements.deleteSelectedBtn.disabled = true;
            updateSelectAllButton();
            
            // 如果没有图片了，显示空状态
            if (state.images.length === 0) {
              renderImages();
            }
            
            showNotification('成功', `已删除 ${deletePromises.length} 张图片`, 'success');
          })
          .catch(error => {
            console.error('删除图片失败:', error);
            showNotification('错误', '删除图片失败', 'error');
          });
      }
    }

    // 处理文件上传
    function handleFileUpload(event) {
      const file = event.target.files[0];
      if (!file) return;
      
      const formData = new FormData();
      formData.append('file', file);
      
      elements.uploadProgressContainer.classList.remove('hidden');
      elements.uploadProgressBar.style.width = '0%';
      elements.uploadProgressText.textContent = '0%';
      
      axios.post('/api/admin/upload', formData, {
        headers: {
          'Content-Type': 'multipart/form-data',
          'Admin-Password': localStorage.getItem('adminPassword')
        },
        onUploadProgress: progressEvent => {
          const percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total);
          elements.uploadProgressBar.style.width = `${percentCompleted}%`;
          elements.uploadProgressText.textContent = `${percentCompleted}%`;
        }
      })
        .then(response => {
          // 将新上传的图片添加到列表顶部
          state.images.unshift(response.data);
          state.totalImages++;
          if (response.data.is_public) {
            state.publicImages++;
          }
          
          // 更新统计信息
          elements.totalImages.textContent = state.totalImages;
          elements.publicImages.textContent = state.publicImages;
          
          // 重新渲染图片网格
          elements.imageGrid.innerHTML = '';
          renderImages();
          
          showNotification('成功', '图片上传成功', 'success');
        })
        .catch(error => {
          console.error('上传图片失败:', error);
          showNotification('错误', '图片上传失败', 'error');
        })
        .finally(() => {
          elements.uploadProgressContainer.classList.add('hidden');
          elements.fileInput.value = '';
        });
    }

    // 处理管理员登录
    function handleAdminLogin() {
      const password = document.getElementById('adminPassword').value;
      
      axios.post('/api/admin/login', { password })
        .then(() => {
          state.isAdmin = true;
          localStorage.setItem('adminLoggedIn', 'true');
          localStorage.setItem('adminPassword', password);
          
          toggleAdminLoginModal();
          document.getElementById('adminPassword').value = '';
          updateAdminUI();
          
          showNotification('成功', '管理员登录成功', 'success');
        })
        .catch(error => {
          console.error('登录失败:', error);
          showNotification('错误', '密码错误', 'error');
        });
    }

    // 处理管理员登出
    function handleLogout() {
      state.isAdmin = false;
      state.selectedImages = [];
      localStorage.removeItem('adminLoggedIn');
      localStorage.removeItem('adminPassword');
      
      updateAdminUI();
      showNotification('提示', '已退出管理员模式', 'info');
    }

    // 切换管理员登录模态框
    function toggleAdminLoginModal() {
      elements.adminLoginModal.classList.toggle('hidden');
    }

    // 更新管理员UI
    function updateAdminUI() {
      if (state.isAdmin) {
        elements.adminPanel.classList.remove('hidden');
        elements.logoutBtn.classList.remove('hidden');
        
        // 更新图片卡片中的管理员控件
        document.querySelectorAll('.admin-controls').forEach(control => {
          control.classList.remove('hidden');
        });
        
        document.querySelectorAll('.image-grid .mt-3').forEach(urlContainer => {
          urlContainer.classList.remove('hidden');
        });
        
        if (state.images.length === 0) {
          elements.noImagesAdminMessage.classList.remove('hidden');
        }
      } else {
        elements.adminPanel.classList.add('hidden');
        elements.logoutBtn.classList.add('hidden');
        state.selectedImages = [];
        
        // 隐藏图片卡片中的管理员控件
        document.querySelectorAll('.admin-controls').forEach(control => {
          control.classList.add('hidden');
        });
        
        document.querySelectorAll('.image-grid .mt-3').forEach(urlContainer => {
          urlContainer.classList.add('hidden');
        });
        
        elements.noImagesAdminMessage.classList.add('hidden');
      }
    }

    // 处理搜索
    function handleSearch() {
      state.searchQuery = elements.searchQuery.value;
      
      // 实际项目中这里应该实现搜索逻辑
      // 本示例中仅作演示，不实现具体搜索功能
      if (state.searchQuery.trim() !== '') {
        showNotification('提示', '搜索功能将在实际部署中实现', 'info');
      }
    }

    // 复制到剪贴板
    function copyToClipboard(text) {
      navigator.clipboard.writeText(text)
        .then(() => {
          showNotification('成功', '已复制到剪贴板', 'success');
        })
        .catch(err => {
          console.error('复制失败:', err);
          showNotification('错误', '复制失败', 'error');
        });
    }

    // 显示通知
    function showNotification(title, message, type = 'success') {
      elements.notificationTitle.textContent = title;
      elements.notificationMessage.textContent = message;
      
      // 设置图标和颜色
      elements.notificationIcon.innerHTML = '';
      let iconClass = 'fa-check-circle';
      let iconColor = 'text-success';
      
      if (type === 'error') {
        iconClass = 'fa-exclamation-circle';
        iconColor = 'text-danger';
      } else if (type === 'warning') {
        iconClass = 'fa-exclamation-triangle';
        iconColor = 'text-warning';
      } else if (type === 'info') {
        iconClass = 'fa-info-circle';
        iconColor = 'text-info';
      }
      
      const icon = document.createElement('i');
      icon.className = `fa ${iconClass} ${iconColor}`;
      elements.notificationIcon.appendChild(icon);
      
      // 显示通知
      elements.notification.classList.remove('translate-y-20', 'opacity-0');
      
      // 3秒后自动关闭
      setTimeout(hideNotification, 3000);
    }

    // 隐藏通知
    function hideNotification() {
      elements.notification.classList.add('translate-y-20', 'opacity-0');
    }

    // 格式化日期
    function formatDate(dateString) {
      if (!dateString) return '';
      
      const date = new Date(dateString);
      return date.toLocaleDateString('zh-CN', {
        year: 'numeric',
        month: 'long',
        day: 'numeric'
      });
    }

    // 防抖函数
    function debounce(func, wait) {
      let timeout;
      return function() {
        const context = this;
        const args = arguments;
        clearTimeout(timeout);
        timeout = setTimeout(() => func.apply(context, args), wait);
      };
    }

    // 初始化应用
    initApp();
  </script>
</body>
</html>    